package com.xiaohudie.servier.Impi;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.xiaohudie.mapper.ShangHuMapper;
import com.xiaohudie.pojo.AjaxResult;
import com.xiaohudie.pojo.ShangHu;
import com.xiaohudie.servier.ShangHuServier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Author xiao hu die
 * @Date 2022/3/3 18:31
 * @Version 1.0
 */
@Service
public class ShangHuServierImpl implements ShangHuServier {
    @Resource
    private ShangHuMapper shangHuMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public ShangHu queryById(Integer id) {
        return shangHuMapper.queryById(id);
    }
    String CacheKey ="cache:";
    @Override
    public AjaxResult cacheById(Integer id) {
        /**从redis中查询有没有这个商户*/
        String s = String.valueOf(id);
        String key ="cache:"+s;
        String shangHuJson = stringRedisTemplate.opsForValue().get(key);
        /**判断是否存在
         * isNotBlank如果是null,"","/t/n",都返回false*/
        if (StrUtil.isNotBlank(shangHuJson)){
            /**redis中就存在了，直接返回*/
            ShangHu shangHu = JSONUtil.toBean(shangHuJson, ShangHu.class);
            return AjaxResult.success(shangHu);
        }
        /**判断是否为空值
         * 如果为空值就不能再次向数据库查了*/
        if (shangHuJson !=null){
            return AjaxResult.error("没有这个店铺");
        }
        /**Redis中不存在*/
        ShangHu shangHu = shangHuMapper.queryById(id);
        /**判断mysql中是否存在*/
        if (shangHu==null){
            /**将空值写入redis
             * 避免缓存穿透问题的解决办法*/
            stringRedisTemplate.opsForValue().set(CacheKey+id,"",10000,TimeUnit.MILLISECONDS);
            return AjaxResult.error("查无此商户");
        }
        /**mysql存在
         * 设置过期时间来保证修改原子性*/
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shangHu),30L, TimeUnit.MINUTES);
        return AjaxResult.success(shangHu);
    }
    /**应对缓存击穿
     * 使用互斥锁来实现*/
    public boolean tryLock(String key){
        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 100000, TimeUnit.MILLISECONDS);
        /**避免拆箱空指针*/
        boolean aTrue = BooleanUtil.isTrue(flag);
        return aTrue;
    }
    /**释放锁*/
    public void delLock(String key){
         stringRedisTemplate.delete(key);

    }

    @Override
    /**加上事务*/
    @Transactional
    public AjaxResult updateShangHu(ShangHu shangHu) {
        if (shangHu.getId()==null){
            return AjaxResult.error("店铺id不存在");
        }
        /**先更新数据库*/
        shangHuMapper.updateShangHu(shangHu);
        /**再删除redis*/
        stringRedisTemplate.delete(CacheKey+shangHu.getId());
        return AjaxResult.success("更新成功");
    }


}
